package com.transaction.simulate.controller;

import com.transaction.common.base.BaseController;
import com.transaction.common.util.ConstUtil;
import com.transaction.common.util.FileUtil;
import com.transaction.common.util.ParamsUtil;
import com.transaction.simulate.mapper.ChannelMapper;
import com.transaction.simulate.model.dto.Channel;
import com.transaction.simulate.model.dto.TextFile;
import com.transaction.simulate.model.vo.ChannelAccountVo;
import com.transaction.simulate.model.vo.TextFileVo;
import com.transaction.simulate.service.FileService;
import com.transaction.simulate.util.AssembleFileUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/file")
public class FileController extends BaseController {

    private static Logger LOGGER = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileService fileService;

    @Autowired
    private ChannelMapper channelMapper;

    ExecutorService executorService;

    //上传文件
    @PostMapping("/fileUpload")
    public Object fileUpload(@RequestParam(value = "files[]", required = false) MultipartFile[] files,
                             String channelCode,
                             String transDate,
                             String fileType){
        //查询渠道信息 没查到抛出异常
        Channel channel = channelMapper.selectChannelByChannelCode(channelCode);
        String creatorCode = channel.getCreatorCode();
        String receiverCode = channel.getReceiverCode();

        StringBuilder retMsg = new StringBuilder();

        for (MultipartFile file :files) {
            String fileName = file.getOriginalFilename();

            if(!fileName.contains(ConstUtil.FILE_PREFIX) &&
                    !fileName.contains(ConstUtil.INDEX_FILE_PREFIX) &&
                    !fileName.contains(ConstUtil.EL_INDEX_FILE_PREFIX) &&
                    !fileName.contains(ConstUtil.FXQ_INDEX_FILE_PREFIX) &&
                    !fileName.contains(ConstUtil.HQ_INDEX_FILE_PREFIX)){
                retMsg.append("文件[").append(fileName).append("]文件名格式不对").append(ConstUtil.LINE_FEED);
                continue;
            }

            /**
             * OFD_009_SH_20220309_01.TXT
             * OFG_009_SH_20220309.TXT
             * OFI_009_SH_20220309.TXT
             * OFX_009_SH_20220309.TXT
             */
            String[] codes = fileName.split(ConstUtil.UNDER_LINE);
            if(codes.length < 4){
                retMsg.append("文件[").append(fileName).append("]文件名格式不对").append(ConstUtil.LINE_FEED);
                continue;
            }

            //fileType  1：申请； 2：确认
            String middle = "";
            if("1".equals(fileType)){
                middle = ConstUtil.UNDER_LINE + creatorCode
                              + ConstUtil.UNDER_LINE + receiverCode
                              + ConstUtil.UNDER_LINE + transDate;
            }else{
                middle = ConstUtil.UNDER_LINE + receiverCode
                        + ConstUtil.UNDER_LINE + creatorCode
                        + ConstUtil.UNDER_LINE + transDate;
            }

            if(!fileName.contains(middle)){
                retMsg.append("文件[").append(fileName).append("]文件名格式与所选条件不符合！").append(ConstUtil.LINE_FEED);
                continue;
            }


            if("1".equals(fileType)){
                String filePath = FileUtil.buildSendFilePath(channel.getChannelCode(),transDate,ConstUtil.TRANSACTION_SIMULATE);
                writeUploadFile(file,filePath);
            }else if(ConstUtil.RECEIVE_FILE_TYPE.contains(fileType)){
                String filePath = FileUtil.buildReceiveFilePath(channel.getChannelCode(),transDate,ConstUtil.TRANSACTION_SIMULATE);
                writeUploadFile(file,filePath);
            }
        }
        return retResultVo(StringUtils.isEmpty(retMsg) ? "上传成功！" : retMsg);
    }

    //解析文件
    @PostMapping("/analysisFileList")
    public Object analysisFileList(@RequestBody TextFileVo textFileVo){
        List<TextFile> textFileList = textFileVo.getTextFileList();

        executorService = Executors.newFixedThreadPool(textFileList.size());
        List<Callable<String>> callAbles = new ArrayList<>();
        textFileList.forEach(v->{
            callAbles.add(new Callable<String>() {
                @Override
                public String call(){
                    return fileService.analysisFile(v);
                }
            });
        });

        List<Future<String>> futureList = null;
        try {
            futureList = executorService.invokeAll(callAbles);
        }catch(Exception e){
            e.printStackTrace();
        }
        String retMsg = futureList.stream().map(future -> {
            try {
                return future.get();
            } catch (Exception e) {
                return null;
            }
        }).collect(Collectors.joining(ConstUtil.LINE_FEED));
        LOGGER.info("{}" , retMsg);
        return retResultVo(retMsg);
    }



    //查询解析文件列表
    @GetMapping("/getAnalysisFileList")
    public Object getAnalysisFileList(HttpServletRequest request){

        Map<String,Object> map = ParamsUtil.getParams(request);
        String channelCode = MapUtils.getString(map,"channelCode");
        String transDate = MapUtils.getString(map,"transDate");
        List<TextFile> list = fileService.getAnalysisFileList(channelCode,transDate);
        return list;
    }


    //下载文件
    @GetMapping("/downLoadFileList")
    public void downLoadFileList(HttpServletResponse response, HttpServletRequest request){
        TextFile textFile = ParamsUtil.getBeanParam(new TextFile(),request);
        String channelCode = textFile.getChannelCode();
        String transDate = textFile.getTransDate();
        String fileDir = FileUtil.buildSendFilePath(channelCode,transDate,ConstUtil.TRANSACTION_SIMULATE);
        String downLoadName = channelCode + "-" + transDate + ConstUtil.COMPRESS_FILE_SUFFIX;
        downLoadFilesToZip(request,response,fileDir,downLoadName);
    }


    //生成渠道文件
    @PostMapping("/generateChannelFile")
    public Object generateChannelFile(@RequestBody ChannelAccountVo channelAccountVo){
        fileService.generateChannelFile(channelAccountVo);
        return retResultVo();
    }

    //解析申请文件内容
    @GetMapping("/getChannelFileDetail")
    public Object getChannelFileDetail(HttpServletRequest request){
        Map<String,Object> map = ParamsUtil.getParams(request);
        Map<String,Object> retMap = fileService.getChannelFileDetail(map);
        return retResultVo(retMap);
    }

    @GetMapping("/getChannelFile")
    public Object getChannelFile(HttpServletRequest request){
        Map<String,Object> map = ParamsUtil.getParams(request);
        return retResultVo(fileService.getChannelFile(map));
    }
}
